#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <string>
#include <cstdio>
#include <unistd.h>

#define SIZE 4096 // 默认4KB

key_t GetCommKey(const std::string &pathname, const int proj_id)
{
    key_t key = ftok(pathname.c_str(), proj_id);
    if (key < 0)
    {
        perror("ftok");
    }
    return key;
}

// 将key转成16进制
std::string ToHeX(key_t key)
{
    char buffer[128];
    snprintf(buffer, sizeof(buffer), "0x%x", key);
    return buffer;
}

//创建共享内存
int CreaterShm(key_t key)
{
    int shmi = shmget(key, SIZE, IPC_CREAT | IPC_EXCL | 0666);
    if (shmi < 0)
        perror("shmget");
    return shmi;
}

//挂接到地址空间
void* AttachShm(int shmi)
{
    void *addrshm = shmat(shmi, nullptr, 0);
    if(addrshm == nullptr)
        perror("shmat");
    return addrshm;
}

//取消挂接
void DetachShm(void *addrshm)
{
    int res = shmdt(addrshm);
    if(res < 0)
        perror("shmdt");
}

//删除共享内存
void DelShm(int shmi)
{
    shmctl(shmi, IPC_RMID, nullptr);
    std::cout << "delete shm...." << std::endl;
}

int main()
{
    const std::string pathname = "/home/cp";
    const int proj_id = 0x666;

    key_t key = GetCommKey(pathname, proj_id);//获取key
    int shmi = CreaterShm(key);//创建共享内存
    void *addrshm = AttachShm(shmi);//挂接
    std::cout << "key: " << ToHeX(key) << std::endl;
    std::cout << "shmi: " << shmi << std::endl;
    sleep(3);
    DetachShm(addrshm);//取消挂接
    DelShm(shmi);

    return 0;
}